package com.scau.jansing.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * todo 增加一个方法，传入一个路径，扫描该路径下某些类的方法是否有@RequestMapping
 * Created by jansing on 2015/11/18.
 */
public class RequestMap {
    //key = @RequestMapping.value;  value = @Bean.value;
    //可以用method.getDeclaringClass() 来获取拥有该方法的类clazz，
    //但是要clazz来从Container中获取对应的obj需要反射（得到key），耗费性能，
    //所以这里用一个map来保存request对应的obj的key
    private static Map<String, String> controllerMap = new HashMap<>();
    //key = @RequestMapping.value;  value = method
    private static Map<String, Method> requestMap = new HashMap<>();


    public static boolean addMethodMap(String clazzName) throws ClassNotFoundException {
        Class clazz = Class.forName(clazzName);
        Method[] methods = clazz.getMethods();
        Method method;
        for (int i = 0; i < methods.length; i++) {
            method = methods[i];
            Iterator<Annotation> annotationIterator = Arrays.asList(method.getDeclaredAnnotations()).iterator();
            while (annotationIterator.hasNext()) {
                Annotation annotation = annotationIterator.next();
                if (annotation.annotationType().equals(RequestMapping.class)) {
                    requestMap.put(((RequestMapping) annotation).value(), method);
                    controllerMap.put(((RequestMapping) annotation).value(), Container.getClazzBeanName(clazz));
                    Field field;
                    break;
                }
            }
        }
        return true;
    }

    public static boolean addMethodMap(Collection<String> clazzNames) throws ClassNotFoundException {
        boolean success = true;
        Iterator<String> iterator = clazzNames.iterator();
        while (iterator.hasNext()) {
            if (!addMethodMap(iterator.next())) {
                success = false;
            }
        }
        return success;
    }

    public static Method getMethod(String key) {
        return requestMap.get(key);
    }

    public static Map<String, Method> getMethodMap() {
        return requestMap;
    }

    public static Set<String> getMethodSet(){
        return requestMap.keySet();
    }

    /**
     * 调用controller目的方法
     * @param request
     */
    public static void invoke(String request, Scanner scanner) throws InvocationTargetException, IllegalAccessException {
        Method method = requestMap.get(request);
        Object obj = Container.getBean(Container.getClazzBeanName(method.getDeclaringClass()));
        method.invoke(obj, scanner);
    }
}
